{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tutorial How-To\n",
    "\n",
    "This tutorial **requires Ollama** for interaction. If you don't have Ollama installed, it's easy, downlaod and install it from here [Ollama installation](https://ollama.com/download)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## How to get started\n",
    "\n",
    "1. Clone this repository to your local machine.\n",
    "\n",
    "2. Install the required dependencies by running the following command:\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install -U ollama;\n",
    "%pip install pickleshare"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. Set up your model name."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "MODEL_NAME = \"qwen2.5:14b\"\n",
    "\n",
    "# Stores the MODEL_NAME variable for use across notebooks within the IPython store\n",
    "%store MODEL_NAME"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. Run the notebook cells in order, following the instructions provided."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Usage Notes & Tips 💡\n",
    "\n",
    "- This course uses [Qwen 2.5 14B](https://ollama.com/library/qwen2.5:14b) with temperature 0. We will talk more about temperature later in the course. For now, it's enough to understand that these settings yield more deterministic results. All prompt engineering techniques in this course also apply to other models available on [Ollama model library](https://ollama.com/search).\n",
    "\n",
    "- You can use `Shift + Enter` to execute the cell and move to the next one.\n",
    "\n",
    "- When you reach the bottom of a tutorial page, navigate to the next numbered file in the folder, or to the next numbered folder if you're finished with the content within that chapter file.\n",
    "\n",
    "### The Ollama Python Library\n",
    "We will be using the [Ollama Python Library](https://github.com/ollama/ollama-python) throughout this tutorial. \n",
    "\n",
    "Below is an example of what running a prompt will look like in this tutorial. First, we create `get_completion`, which is a helper function that sends a prompt to Ollama and returns Ollama's generated response. Run that cell now."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ollama import chat, ChatResponse, Options\n",
    "\n",
    "def get_completion(prompt: str):\n",
    "    response = chat(\n",
    "        model=MODEL_NAME,\n",
    "        options=Options(\n",
    "            max_tokens=2000,\n",
    "            temperature=0.0,\n",
    "        ),\n",
    "        messages=[\n",
    "          {\"role\": \"user\", \"content\": prompt}\n",
    "        ]\n",
    "    )\n",
    "    return response.message.content"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's download the required model first, MODEL_NAME variable defined above will be used to determine the model to be used throughout the tutorial. Executing the cell below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from tqdm import tqdm\n",
    "from ollama import pull\n",
    "\n",
    "\n",
    "current_digest, bars = '', {}\n",
    "for progress in pull(MODEL_NAME, stream=True):\n",
    "  digest = progress.get('digest', '')\n",
    "  if digest != current_digest and current_digest in bars:\n",
    "    bars[current_digest].close()\n",
    "\n",
    "  if not digest:\n",
    "    print(progress.get('status'))\n",
    "    continue\n",
    "\n",
    "  if digest not in bars and (total := progress.get('total')):\n",
    "    bars[digest] = tqdm(total=total, desc=f'pulling {digest[7:19]}', unit='B', unit_scale=True)\n",
    "\n",
    "  if completed := progress.get('completed'):\n",
    "    bars[digest].update(completed - bars[digest].n)\n",
    "\n",
    "  current_digest = digest"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we will write out an example prompt for Ollama and print Ollama's output by running our `get_completion` helper function. Running the cell below will print out a response from Ollama beneath it.\n",
    "\n",
    "Feel free to play around with the prompt string to elicit different responses from Ollama."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Prompt\n",
    "prompt = \"Hello! Who are you?\"\n",
    "\n",
    "# Get Ollama's response\n",
    "print(get_completion(prompt))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `MODEL_NAME` variables define earlier will be used throughout the tutorial. Just make sure to run the cells for each tutorial page from top to bottom."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
